Постановка задачи
Представим, что мы имеем
v_reg
— набор виртуальных регистровphys_reg
— набор физических регистровбазовый блок размера
basic_block_size
, который представляет собой последовательность инструкций. Каждая инструкцияиспользует до
инструкции_max
виртуальных регистровможет быть определением нового виртуального регистра (а может и нет).
Задача регистровой аллокации задаётся вопросом:
Есть ли отображение v_reg
→ phys_reg
, такое, что для любой инструкции образ её используемых регистров не будет содержать одинаковых физических регистров.
Также мы предполагаем, что после использования регистра (??физического??) он сразу же сохраняется в памяти, а перед использованием из неё достаётся, что позволяет нам присваивать одинаковые физические регистры тем виртуальным регистрам, live ranges которых пересекаются.
В настоящем аллокаторе, конечно же, для поиска оптимальных spill/restore промежутков используется отдельная эвристика жадного «разрезания», старающая минимизировать количество операций с памятью).
Оптимизационная версия задачи «минимальная локальная регистровая аллокация», задаёт вопрос об аллокации минимальной стоимости, то есть минимизируем сумму использования регистра на стоимость использования по всем операндам всех инструкций.
Stas: инструкции_max — получается 1, и регистр «1» изначально не используется. Что-то как-то некрасиво.
Для визуализации будем считать, что
каждая строка представляет инструкцию,
каждый столбец представляет использование i-го виртуального регистра.
alloca | ||
---|---|---|
0 | 0 | 1.0 |
1 | 0 | 1.0 |
2 | 0 | 1.0 |
3 | 0 | 1.0 |
4 | 0 | 1.0 |
5 | 0 | 1.0 |
6 | 0 | 1.0 |
7 | 0 | 1.0 |
8 | 0 | 1.0 |
вирт2физ | ||
---|---|---|
00 | 0 | 1.0 |
02 | 0 | 1.0 |
03 | 0 | 1.0 |
04 | 0 | 1.0 |
05 | 0 | 1.0 |
06 | 0 | 1.0 |
Визуализируем используемые регистры инструкций после аллокации (заменим виртуальные регистры на физические)